home *** CD-ROM | disk | FTP | other *** search
- /*
- * play.c - routines to load and play an IFF 8SVX sound
- *
- * Bruno Costa - 19 Feb 91 - 19 Feb 91
- *
- * (based on ARKM 1.3 example audio2.c)
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <devices/audio.h>
- #include <libraries/dos.h>
- #include <graphics/gfxbase.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
-
- #include <stdlib.h>
- #include <stdio.h>
-
- #include "iff.h"
-
- #define VHDR MakeID('V','H','D','R')
- #define BODY MakeID('B','O','D','Y')
- #define MY8S MakeID('8','S','V','X')
-
-
- static struct MsgPort *port; /* audio device port */
-
- static UBYTE *fbuf; /* For sample memory allocation */
- static ULONG fsize; /* and freeing */
-
- static Voice8Header *header;
- static UBYTE *sample; /* one-shot sample data */
- static ULONG length; /* Sample length */
- static ULONG clock;
-
- static struct IOAudio *AIOreq;
- static int posted = FALSE;
-
-
- static void setclock (void)
- {
- struct GfxBase *gbase;
-
- clock = 3579545L; /* NTSC clock */
-
- gbase = (struct GfxBase *) OpenLibrary ("graphics.library", 0L);
- if (gbase)
- {
- if (gbase->DisplayFlags & PAL)
- clock = 3546895L; /* PAL clock */
-
- CloseLibrary ((struct Library *) gbase);
- }
- }
-
-
- static void abort (void)
- {
- if (posted && !CheckIO ((struct IORequest *) AIOreq))
- AbortIO ((struct IORequest *) AIOreq);
- }
-
-
- static void wait (void)
- {
- if (posted)
- {
- WaitPort (port);
- (void) GetMsg (port);
- posted = FALSE;
- }
- }
-
-
- static int sopen (void)
- {
- static UBYTE chan1[] = { 1 }; /* Audio channel allocation arrays */
- static UBYTE chan2[] = { 2 };
- static UBYTE chan3[] = { 4 };
- static UBYTE chan4[] = { 8 };
- static UBYTE *chans[] = {chan1,chan2,chan3,chan4};
-
- ULONG speed = clock / header->samplesPerSec;
-
- AIOreq = (struct IOAudio *) AllocMem (sizeof (*AIOreq), MEMF_PUBLIC | MEMF_CLEAR);
- if (AIOreq)
- {
- port = CreatePort (0, 0);
- if (port)
- {
- int err;
- int c = 0; /* start by channel 0 */
-
- do
- {
- AIOreq->ioa_Request.io_Message.mn_ReplyPort = port;
- AIOreq->ioa_Request.io_Message.mn_Node.ln_Pri = 128; /* No stealing! */
- AIOreq->ioa_AllocKey = 0;
- AIOreq->ioa_Data = chans[c];
- AIOreq->ioa_Length = 1;
-
- err = OpenDevice ("audio.device", 0L, (struct IORequest *) AIOreq, 0L);
- ++c;
- } while (err != 0 && c < 4);
-
- if (!err)
- {
- AIOreq->ioa_Request.io_Command = CMD_WRITE;
- AIOreq->ioa_Request.io_Flags = ADIOF_PERVOL;
- AIOreq->ioa_Volume = 60;
-
- AIOreq->ioa_Period = (UWORD)speed;
- AIOreq->ioa_Cycles = 1;
-
- AIOreq->ioa_Request.io_Message.mn_ReplyPort = port;
-
- AIOreq->ioa_Data = sample;
-
- return TRUE; /* normal return is here */
- }
- DeletePort (port);
- }
- FreeMem (AIOreq, sizeof (*AIOreq));
- }
-
- return FALSE;
- }
-
-
- static void sclose (void)
- {
- abort ();
- wait ();
-
- CloseDevice ((struct IORequest *) AIOreq);
- if (port)
- DeletePort (port);
- if (AIOreq)
- FreeMem (AIOreq, sizeof (*AIOreq));
- }
-
-
- void play (void)
- {
- abort ();
- wait ();
-
- if (length > 0 && length <= 102400)
- {
- AIOreq->ioa_Length = length;
- BeginIO ((struct IORequest *) AIOreq);
- posted = TRUE;
- }
- }
-
-
- int load (char *fname)
- {
- UBYTE *data; /* data ptr for file read */
- BYTE iobuffer[8]; /* Buffer for 8SVX header */
- Chunk *chunk; /* Pointers for 8SVX parsing */
- BPTR f;
-
- setclock ();
-
- f = Open (fname, MODE_OLDFILE);
- if (f)
- {
- long count = Read (f, iobuffer, 8L);
- if (count == 8)
- {
- chunk = (Chunk *)iobuffer;
- if(chunk->ckID == FORM)
- {
- fsize = chunk->ckSize;
- fbuf = AllocMem (fsize, MEMF_CHIP | MEMF_CLEAR);
- if (fbuf)
- {
- data = fbuf;
- count = Read (f, fbuf, chunk->ckSize);
- if (count == chunk->ckSize)
- {
- if (MakeID (*data, *(data+1), *(data+2), *(data+3)) == MY8S)
- {
- data += 4;
-
- while (data < fbuf + fsize)
- {
- chunk = (Chunk *)data;
-
- switch (chunk->ckID)
- {
- case VHDR:
- header = (Voice8Header *) (data + 8);
- break;
-
- case BODY:
- sample = (BYTE *)(data + 8);
- length = header->oneShotHiSamples;
- if (length == 0)
- length = header->repeatHiSamples;
- break;
- }
-
- data += 8 + chunk->ckSize;
-
- if (chunk->ckSize & 1L == 1)
- data++;
- }
- Close (f);
-
- if (sopen ())
- return TRUE; /* normal exit is here */
- }
- }
- FreeMem (fbuf, fsize);
- }
- }
- }
- Close (f);
- }
-
- return FALSE;
- }
-
-
- void unload (void)
- {
- sclose ();
-
- if (fbuf)
- FreeMem (fbuf, fsize);
-
- fbuf = NULL;
- fsize = 0;
- }
-
-
- #ifdef TEST
- void main (int argc, char *argv[])
- {
- if (argc != 2)
- {
- printf ("usage: %s <sound file>\n", argv[0]);
- exit (10);
- }
-
- if (load (argv[1]))
- {
- play ();
- wait ();
- unload ();
- }
- }
- #endif
-